package org.liang.job.repository;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.liang.jdbc.repository.BaseRepository;
import org.liang.job.beans.Job;
import org.liang.job.common.IDBuilder;
import org.springframework.stereotype.Repository;

/**
 * 自动任务数据库操作类.
 * 
 * <pre>
 * 提供以下行为：
 * 1. 单独任务保存
 * 2. 批量任务保存
 * 3. 删除指定任务
 * 4. 删除指定组内的任务
 * </pre>
 * 
 * @author L.Yang
 * @version 1.0, 2015年9月23日
 */
@Repository("schedulerUpdateRepository")
public class SchedulerUpdateRepository extends BaseRepository {

    /** 自动任务表. */
    private static final String JOB_TABLE = "TASK_AUTO_JOB";

    /** 自动任务参数表. */
    private static final String PARAM_TABLE = "TASK_JOB_PARAM";

    /**
     * 将任务信息存到数据库重.
     * 
     * @param job
     *            任务实体
     */
    public void save(Job job) {
        // 将任务及参数信息保存到数据库
        // 保存 job 信息
        String jobId = IDBuilder.buildUniqueID();
        String sql4job = "insert into " + JOB_TABLE + "(ID, TITLE, NAME, GROUP_ID, BIZ) values "
                         + buildPreparedStatement4Args(5);
        Object[] args4job =
                new Object[] {jobId, job.getTitle(), job.getName(), job.getGroup(), job.getBiz()};
        getJdbcTemplate().update(sql4job, args4job);
        // 保存 job parma 信息
        String sql4param = "insert into " + PARAM_TABLE + "(ID, JOB_ID, P_KEY, P_VAL) values"
                           + buildPreparedStatement4Args(4);
        List<Object[]> batchArgs = new ArrayList<Object[]>();
        Map<String, Object> params = job.getArgs();
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            Object[] args = 
                new Object[] {IDBuilder.buildUniqueID(), jobId, entry.getKey(), entry.getValue()};
            batchArgs.add(args);
        }
        getJdbcTemplate().batchUpdate(sql4param, batchArgs);
    }

    /**
     * 将任务批量存入数据库中.<br>
     * 先对任务进行批量保存，然后对任务参数进行批量保存
     * 
     * @param jobs
     *            任务列表
     */
    public void save(List<Job> jobs) {
        Map<String, Map<String, Object>> args = batchSave4Job(jobs);
        batchSave4Param(args);
    }

    /**
     * 批量保存.
     * 
     * @param jobs
     *            任务列表
     * @return 任务参数集合 {key:jobId, value:params}
     */
    private Map<String, Map<String, Object>> batchSave4Job(List<Job> jobs) {
        Map<String, Map<String, Object>> params = new HashMap<String, Map<String, Object>>();
        List<Object[]> batchArgs = new ArrayList<Object[]>();
        String sql = "insert into " + JOB_TABLE + "(ID, TITLE, NAME, GROUP_ID, BIZ) values "
                     + buildPreparedStatement4Args(5);
        for (Job job : jobs) {
            String jobId = IDBuilder.buildUniqueID();
            params.put(jobId, job.getArgs());
            batchArgs.add(
                new Object[] {jobId, job.getTitle(), job.getName(), job.getGroup(), job.getBiz()});
        }
        getJdbcTemplate().batchUpdate(sql, batchArgs);
        return params;
    }

    /**
     * 批量保存任务参数信息.
     * 
     * @param params
     *            任务参数集合{key:jobId, value:params}
     */
    private void batchSave4Param(Map<String, Map<String, Object>> params) {
        String sql = "insert into " + PARAM_TABLE + "(ID, JOB_ID, P_KEY, P_VAL) values"
                     + buildPreparedStatement4Args(4);
        List<Object[]> batchArgs = new ArrayList<Object[]>();
        for (Map.Entry<String, Map<String, Object>> paramEntry : params.entrySet()) {
            String jobId = paramEntry.getKey();
            for (Map.Entry<String, Object> onceEntry : paramEntry.getValue().entrySet()) {
                String id = IDBuilder.buildUniqueID();
                batchArgs.add(new Object[] {id, jobId, onceEntry.getKey(), onceEntry.getValue()});
            }
        }
        getJdbcTemplate().batchUpdate(sql, batchArgs);
    }

    /**
     * 删除指定任务.<br>
     * 删除任务的同时，会将该任务的业务参数都删除
     * 
     * @param name
     *            任务名
     * @param group
     *            任务组
     */
    public void delete(String name, String group) {
        Object[] args = new Object[] {name, group};
        // 删除该job的参数
        String sql4param = "delete from " + PARAM_TABLE + " where "
            + "JOB_ID in (select t.ID from " + JOB_TABLE + " t where t.NAME=? and t.GROUP_ID=?)";
        getJdbcTemplate().update(sql4param, args);
        // 参数该job
        String sql4job = "delete from " + JOB_TABLE + " where NAME = ? and GROUP_ID=?";
        getJdbcTemplate().update(sql4job, args);
    }

    /**
     * 删除指定组内的任务. <br>
     * 删除任务的同时，会将该任务的业务参数都删除
     * 
     * @param group
     *            任务组
     */
    public void delete(String group) {
        Object[] args = new Object[] {group};
        // 删除该job的参数
        String sql4param = "delete from " + PARAM_TABLE + " where "
                        + "JOB_ID in (select t.ID from " + JOB_TABLE + " t where t.GROUP_ID=?)";
        getJdbcTemplate().update(sql4param, args);
        // 参数该job
        String sql4job = "delete from " + JOB_TABLE + " where GROUP_ID=?";
        getJdbcTemplate().update(sql4job, args);
    }
}
